------------------------------------
-- Setup the backpack table.
------------------------------------
local function SetupBackpack(ply)
	ply.Backpack = {}
end
hook.Add("PlayerInitialSpawn", "SetupBackpack", SetupBackpack)

------------------------------------
-- Player drops an item from the backpack.
------------------------------------
local function DropItem(ply, cmd, args)
	if (args[1]==nil) then 
		return 
	end
	local item
	for k, v in ipairs(ply.Backpack) do 
		if(v[1] == args[1]) then 
			item = k
			break
		end
	end
	local trace = { }
		trace.start = ply:EyePos()
		trace.endpos = trace.start + ply:GetAimVector() * 150
		trace.filter = ply
	local tr = util.TraceLine(trace)
	
	if(ply.Backpack[item] != nil) then
		local weapon = ents.Create(ply.Backpack[item][1])
			weapon:SetPos(tr.HitPos+Vector(0,0,10))
		weapon:Spawn()
		table.remove(ply.Backpack, item)
	end
end
concommand.Add("backpack_drop", DropItem)

------------------------------------
-- Drop all items in the backpack.
------------------------------------
local function DropItems(ply)
	local i = 0
	
	local trace = { }
		trace.start = ply:EyePos()
		trace.endpos = trace.start + ply:GetAimVector() * 150
		trace.filter = ply
	local tr = util.TraceLine(trace)
	
	for k,v in ipairs(ply.Backpack) do
		local weapon = ents.Create(v[1])
			weapon:SetPos(tr.HitPos+Vector(0,0,10+(i*10)))
		weapon:Spawn()
		i = 1 + i
	end
	ply.Backpack = {}
	return ""
end
AddChatCommand("/dropbackpack", DropItems)

------------------------------------
-- A player dies, spawns items.
------------------------------------
local function PlyDeath(ply, weapon, killer)
	for k,v in ipairs(ply.Backpack) do
		local weapon = ents.Create(v[1])
			weapon:SetPos(ply:GetPos()+Vector(math.random(-10,10),math.random(-10,10),math.random(10,40)))
		weapon:Spawn()
	end
	ply.Backpack = {}
end
hook.Add("PlayerDeath", "PlyDeath", PlyDeath)

------------------------------------
-- Player tries to put item in backpack.
------------------------------------
local function PickupItem(ply)
	local trace = { }
		trace.start = ply:EyePos()
		trace.endpos = trace.start + ply:GetAimVector() * 150
		trace.filter = ply
	local tr = util.TraceLine(trace)
	
	if (!ValidEntity(tr.Entity)) then return "" end
	
	if(!string.find(tr.Entity:GetClass(), "item_") && !string.find(tr.Entity:GetClass(), "drug_") && !string.find(tr.Entity:GetClass(), "ammo_") && !tr.Entity:IsWeapon()) then return "" end
	
	if(table.Count(ply.Backpack)>=20) then Notify(ply, 4, 3, "Your backpack is full!") return "" end

	local target = tr.Entity
	local gun
	local model
	local class
	local isupgraded
	
	if(tr.Entity:IsWeapon()) then gun = true else gun = false end
	
	table.insert(ply.Backpack, {target:GetClass(), target:GetModel(), gun, isupgraded})
	target:Remove()
	Notify(ply, 0, 3, target.PrintName .. "added to your backpack!")
	ply:EmitSound("Flesh.ImpactSoft")
	return ""
end
AddChatCommand("/backpack", PickupItem)

------------------------------------
-- +/-backpack commands/timers.
------------------------------------
local function StartPickupItem(ply)
	if(timer.IsTimer(ply:UniqueID() .. "BACKPACKPICKUP") == false) then
		timer.Create(ply:UniqueID() .. "BACKPACKPICKUP", 0.1, 200, function() PickupItem(ply) end)
	end
end
concommand.Add("+backpack", StartPickupItem)

local function StopPickupItem(ply)
	timer.Destroy(ply:UniqueID() .. "BACKPACKPICKUP")
end
concommand.Add("-backpack", StopPickupItem)

------------------------------------
-- Open the inventory menu to the player.
------------------------------------
local function ShowIventory(ply)
	datastream.StreamToClients(ply, "ShowInventorySteam", {ply.Backpack})
end
hook.Add("ShowTeam", "ShowIventory", ShowIventory)